package cn.com.dodo.demo.aoplog.aspect;

import cn.com.dodo.demo.aoplog.annotation.Log;
import cn.com.dodo.demo.aoplog.dao.SysLogDao;
import cn.com.dodo.demo.aoplog.domain.SysLog;
import cn.com.dodo.demo.aoplog.util.HttpContextUtils;
import cn.com.dodo.demo.aoplog.util.IPUtils;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.LocalVariableTableParameterNameDiscoverer;
import org.springframework.stereotype.Component;

import javax.servlet.http.HttpServletRequest;
import java.lang.reflect.Method;

@Aspect
@Component
public class LogAspect {
    @Autowired
    private SysLogDao sysLogDao;

    @Pointcut("@annotation(cn.com.dodo.demo.aoplog.annotation.Log)")
    private void pointcut() {
    }

    @Around("pointcut()")
    public void around(ProceedingJoinPoint point) {
        long beginTime = System.currentTimeMillis();
        try {
            point.proceed();
        } catch (Throwable e) {
            e.printStackTrace();
        }
        long time = System.currentTimeMillis() - beginTime;
        saveLog(point, time);
    }

    private void saveLog(ProceedingJoinPoint point, long time) {
        try {
            MethodSignature signature = (MethodSignature) point.getSignature();
            Method method = signature.getMethod();
            SysLog sysLog = new SysLog();
            Log logAnnotation = method.getAnnotation(Log.class);
            if (logAnnotation != null) {
                sysLog.setOperation(logAnnotation.value());
            }
            String className = point.getTarget().getClass().getName();
            String methodName = signature.getName();
            sysLog.setMethod(className + "." + methodName);
            Object[] args = point.getArgs();

            LocalVariableTableParameterNameDiscoverer u = new LocalVariableTableParameterNameDiscoverer();
            String[] paramNames = u.getParameterNames(method);
            if (args != null && paramNames != null) {
                StringBuilder params = new StringBuilder();
                for (int i = 0; i < args.length; i++) {
                    params.append("  ");
                    params.append(paramNames[i]).append(": ").append(args[i]);
                }
                sysLog.setParams(params.toString());
            }

            HttpServletRequest request = HttpContextUtils.getHttpServletRequest();
            sysLog.setIp(IPUtils.getIpAddr(request));
            sysLog.setUsername("sys");

            sysLog.setTime((int) time);
            sysLogDao.saveSysLog(sysLog);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

}
